<?php

namespace App\Http\Controllers\Admin;

use App\Common\SDK\Facade\ZhiLing;
use App\Http\Controllers\Controller;
use App\Models\Administrator;
use App\Models\SmsLog;
use App\Services\Authorization;
use App\Services\Captcha;
use Carbon\Carbon;
use Dingo\Api\Http\Request;
use Gregwar\Captcha\CaptchaBuilder;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    public function store(Request $request)
    {
        if (!$token = Auth::attempt(
            Arr::add($request->only(['account', 'password']), 'status', Administrator::STATUS_NORMAL)
        )) {
            $this->response->errorUnauthorized(trans('auth.incorrect'));
        }

        return $this->response->created(null, (new Authorization($token))->toArray());
    }

    public function update()
    {

        return $this->response->created(null, (new Authorization(Auth::refresh()))->toArray());
    }

    public function destory()
    {
        Auth::logout();

        return $this->response->noContent();
    }

    public function info()
    {
        try {
            $user = Auth::user()->toArray();
        } catch (\Exception $e) {
            $this->response->errorForbidden();
        }

        return $this->response->array(
            array_merge(
                $user,
                [
                    'permissions' => (empty($permissions = Auth::user()->getAllPermissions()->pluck('name')->toArray()) ? ['index'] : $permissions)
                ]
            )
        );
    }

    public function picCaptcha()
    {
        $captcha = (new CaptchaBuilder())->build();

        $uuid = Str::uuid()->toString();
        Redis::setex('admin_captcha_' . $uuid, 60, $captcha->getPhrase());

        return $this->response->array([
            'image' => base64_encode($captcha->get()),
            'uuid' => $uuid,
            'expire' => 60
        ]);
    }

    public function smsCaptcha(Request $request)
    {
        if (($captcha = Redis::get('admin_captcha_' . $request->get('uuid'))) === null
            || strtolower($captcha) !== strtolower($request->get('pic_captcha'))) {
            return $this->response->errorBadRequest('图片验证码错误或者已过期');
        }

        try {
            DB::beginTransaction();

            $phone = $request->get('phone');
            $code = random_int(100000, 999999);
            $uuid = Str::uuid();
            $content = sprintf('您的验证码是%d', $code);
            $expiredAt = Carbon::now()->addMinutes(15)->timestamp;
            $sms = SmsLog::create([
                'phone' => $phone,
                'content' => $content,
                'properties' => [
                    'code' => $code,
                    'expired_at' => $expiredAt,
                    'uuid' => $uuid,
                ],
                'type' => SmsLog::TYPE_CAPTCHA,
            ]);

            ZhiLing::sms([
                'phones' => $phone,
                'sms_body' => $content,
                'sms_sign' => env('ZHI_LING_SMS_SIGN', '省到家'),
            ]);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();

            $this->response->errorBadRequest($e->getMessage());
        }

        return $this->response->created(null, [
            'uuid' => $uuid,
            'expired_at' => $expiredAt
        ]);
    }

    public function verificationSmsCaptcha(Request $request)
    {
        if (!Captcha::verificationSmsCaptcha($request)) {
            $this->response->errorBadRequest('短信验证码错误或者已过期');
        }
        return $this->response->accepted();
    }

    public function resetPassword(Request $request)
    {
        if (!Captcha::verificationSmsCaptcha($request)) {
            $this->response->errorBadRequest('短信验证码错误或者已过期');
        }

        Administrator::query()
            ->where('phone', $request->phone)
            ->update(['password' => Hash::make($request->new_password)]);

        return $this->response->created();
    }
}
